﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using MvcContrib;
using Wayloop.Blog.Core.Data;
using Wayloop.Blog.Core.Data.Entities;
using Wayloop.Blog.Core.Markup;
using Wayloop.Blog.Core.Services;


namespace Wayloop.Blog.Presentation.Controllers
{
    public class PostController : AbstractController
    {
        /// <summary>
        /// Gets or sets the <see cref="INotificationService"/> implementation.
        /// </summary>
        /// <value>The <see cref="INotificationService"/> implementation.</value>
        public INotificationService NotificationService { get; private set; }


        /// <summary>
        /// Gets or sets the <see cref="IPostRepository"/> implementation.
        /// </summary>
        /// <value>The <see cref="IPostRepository"/> implementation.</value>
        public IPostRepository PostRepository { get; private set; }


        /// <summary>
        /// Initializes a new instance of the <see cref="PostController"/> class.
        /// </summary>
        /// <param name="notificationService">The notification service.</param>
        /// <param name="postRepository">The <see cref="IPostRepository"/> implementation.</param>
        public PostController(INotificationService notificationService, IPostRepository postRepository)
        {
            NotificationService = notificationService;
            PostRepository = postRepository;
        }


        /// <summary>
        /// Lists the most recent blog posts.
        /// </summary>
        /// <returns>A view that lists the most recent blog posts.</returns>
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Index()
        {
            IEnumerable<Post> posts = PostRepository.FindAllPublished(0, 10);
            ViewData["posts"] = posts;
            return View();
        }


        /// <summary>
        /// Lists all published blog posts.
        /// </summary>
        /// <returns>A view that lists the blog posts.</returns>
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Archive()
        {
            IEnumerable<Post> posts = PostRepository.FindAllPublished();
            ViewData["posts"] = posts;
            return View();
        }


        /// <summary>
        /// Displays the blog post that matches the specified slug.
        /// </summary>
        /// <param name="slug">The slug.</param>
        /// <returns>A view that displays the blog post.</returns>
        /// <remarks>If any of the date parts are incorrect, a redirect result is returned with correct date parts.</remarks>
        [AcceptVerbs(HttpVerbs.Get)]
        public ActionResult Show(string slug)
        {
            Post post = PostRepository.Find(slug);
            if (post == null) {
                throw new HttpException(404, "No post found that matches the specified slug.");
            }

            ViewData["post"] = post;
            return View();
        }


        [AcceptVerbs(HttpVerbs.Post), ValidateInput(false), ValidateAntiForgeryToken]
        public ActionResult AddComment(string slug, Comment comment, string fakeCaptcha)
        {
            Post post = PostRepository.Find(slug);

            if (!fakeCaptcha.Equals("3", StringComparison.InvariantCultureIgnoreCase)) {
                ModelState.AddModelError("fakeCaptcha", "The answer is incorrect...");
            }

            if (ModelState.IsValid) {
                comment.Body = HtmlSanitizer.Sanitize(comment.Body).Replace(Environment.NewLine, "<br/>");
                comment.CreatedOn = DateTime.UtcNow;
                comment.Status = CommentStatus.Normal;

                post.AddComment(comment);
                PostRepository.Save(post);

                NotificationService.SendNotification("New comment posted", comment.Body);

                return this.RedirectToAction(c => c.Show(slug));
            }

            ViewData["post"] = post;
            return View("Show");
        }
    }
}